<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mload</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    <script src="https://cdn.bootcss.com/spin.js/2.3.2/spin.min.js"></script>

    <link href="https://cdn.bootcss.com/highlight.js/9.12.0/styles/atom-one-light.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>
    <script>hljs.initHighlightingOnLoad();</script>

    <script src="../src/mload.js"></script>

</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-12">
            <h1 class="bd-title" id="content">Mload</h1>
            <p>
                移动端专用的异步列表加载插件
            </p>
            <div>
                灵活支持各种过滤参数。
                <br>
                列表内容返回后可还原列表页状态。
                <span>比如商品列表，新闻列表进入内容页后，回退到列表页时可还原列表的操作状态。</span>
                <br>
                一个页面支持多个实例。
            </div>
        </div>

        <div class="col-12">
            <h4>Useage</h4>
            <pre>
                <code>
&lt;script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="mload.js"&gt;&lt;/script&gt;
                </code>
            </pre>
            <p>初始化</p>
            <pre>
                <code>
$(function () {
    $('#c').mload({//'#c'是一个高度可变容器，他的父节点可以是固定高的容器，也可以不指定这个父节点，这样就以页面窗口作固定高的容器。
        protect:'.loadmorec,.loadmore',//保护指定的容器下的内容，可指定多个需要保护的容器
        filter:function (i) {//第一个参数i为对象实例
            var filter = {}
            filter = $('#cf').change(function () {//同时这也是一个初始方法，可以做一些事件操作，return的数据作为初始过滤条件
                //条件改变时重新加载列表
                i.setfilter($(this).serializeArray()).reload()
            }).serializeArray()a
            return filter;//这里返回初始的过滤条件对象，有效示例：{'age':28,'name':'andy'} or  [{name: 'age', value: 28},{name: 'name', value: 'andy'}]
        },//初始数据过滤条件
        loadprocess:function (i) {//列表数据加载
            var target = $(i.target)
            var filter = i.filter
            filter['limit'] = 10
            filter['skip'] = i.offset* filter['limit']

            i.ajax({ //此处ajax方法用法和$.ajax一致，但是不能用$.ajax代替
                url:'c.php',
                type:'GET',
                data:filter,
                success:function (response,status) {
                    if(response.end===true){
                        i.end=true;//标记列表数据已经全部加载完毕，这时会回调completed
                    }
                    $(target).append(response) //将获取到的内容追加到列表容器，通常是html内容，当然也可以是其它形式的数据（如json）处理成html内容后追加
                    $('.loadmorec').text('加载完成')
                },
                error:function (response,status) {
                    //do something
                }
            })
        },
        beforeLoad:function (i) {//即将开始加载列表页之前回调，通常可以做一些loading效果
            $('.loadmorec').text('加载中..')
        },
        completed:function (jqHXR) {//列表全部加载完成时回调
            $('.loadmorec').text('没有更多内容')
        }
    })
})
                </code>
            </pre>

        </div>

        <div class="col-12">
            <h4>Options</h4>
            <p>
                <code>protect</code>: (string)
                <br>
                使用jquery选择器指定保护当前页面上的部分html结构。回退时可以还原html结构。
            </p>

            <p>
                <code>mab</code>: (int)
                <br>
                定义预加载高度，当滑动离窗口或容器底部小于该像素高度时，开始加载下一页列表。
            </p>

            <p>
                <code>filter</code>: (obj,function or array)
                <br>
                初始过滤，列表在初始时通常会首次加载前几页列表数据，可以为其指定初始过滤条件。
                <br>
                示例：
            <pre>
            <code>{'age':28,'name':'andy'} or  [{name: 'age', value: 28},{name: 'name', value: 'andy'}] ($.serializeArray()的返回形式)
            </code>
            </pre>

                <br>
                通常建议使用function来处理，这样做的好处就是可以在方法体中完成其它一些初始操作，请参考demo.
            </p>

            <h4>实例属性</h4>
            <p>
                <code>target</code>
                <br>
                放置列表内容的目标容器选择器字符串。
            </p>
            <p>
                <code>offset</code>
                <br>
                分页偏移量，初始偏移为0。每加向后加载一次，offset自增1。通常用于计算数据库query的skip值。
            </p>

            <p>
                <code>end</code>
                <br>
                手动end=true时，标记本列表实例已经全部加载完毕。
                <br>
                此属性也可以自动标记，当单次分页加载完毕后，目标容器的高度没有再增加或者ajax的status不等于success时，则自动end=true.

            </p>

            <h4>实例方法</h4>
            <p>
                <code>setfilter(filter)</code>
                <br>
                更新过滤条件，数据格式同 <code>filter</code>属性。
            </p>

            <p>
                <code>reload()</code>
                <br>
                offset置为0，实现重新让列表从首页偏移开始加载，通常配合 <code>setfilter(filter)</code>连贯使用。
            </p>

            <p>
                <code>ajax()</code>
                <br>
                异常加分页数据方法，用法同jQuery.ajax(),但是不能用代替使用，否则无法正确触发completed事件。
            </p>

            <h4>事件</h4>
            <p>
                <code>loadprocess(i)</code>
                <br>
                开始加载新列表页，第一个参数i即实例对象，可以访问到target,offset属性，还可以标记end属性。
                重点，这里请使用i.ajax()去请求新列表页面，用法和jQuery.ajax()方法一致。并且你需要自己处理响应结果。
            </p>
            <p>
                <code>beforeLoad(i)</code>
                <br>
                第一个参数i即实例对象。
                即将开始加载列表页之前回调，通常可以做一些loading效果
            </p>
            <p>
                <code>completed(response,status,i)</code>
                <br>
                参数i即实例对象。
                列表全部加载完成时回调。
            </p>

        </div>


        <div class="col-12">
            <h4>Demo1</h4>
            <p>
                这是一个高度固定的容器。
            </p>
            <div>
                <form class="form-horizontal" id="cf">

                    <div class="input-group">
                        <input type="text" class="form-control" name="search" placeholder="关键字搜索">
                        <span class="input-group-append">
                        <button class="btn btn-outline-secondary" type="submit" >搜索</button>
                    </span>
                    </div>

                    <div class="btn-group btn-group-toggle" data-toggle="buttons">
                        <label class="btn btn-primary">
                            <input type="radio" name="radio" value="male" autocomplete="off" > 男
                        </label>
                        <label class="btn btn-primary active">
                            <input type="radio" name="radio" value="female" autocomplete="off" checked> 女
                        </label>
                        <label class="btn btn-primary">
                            <input type="radio" name="radio" value="unknow" autocomplete="off"> 未知
                        </label>
                    </div>
                </form>
            </div>
            <div style="height: 200px;overflow: auto;margin-bottom: 20px;"><!--固定高度的容器-->
                <ul  class="list-group"  id="c" >

                </ul>
                <div class="loadmorec text-center"  style="height: 50px;line-height: 50px;">...</div>
            </div>

        </div>
    </div>

    <h4>Demo2</h4>
    <p>
        parents中没有一个是固定高度的容器，就以可视范围为容器
    </p>
    <div class="row">
        <div class="col-12">
            <form class="form-horizontal" id="demo">
                <div class="input-group">
                    <input type="text" class="form-control" name="find" placeholder="Find...">
                    <span class="input-group-append">
                        <button class="btn btn-outline-secondary" type="submit" >搜索</button>
                    </span>
                </div>
            </form>
            <div id="list"><!--parents中没有一个是固定高度的容器，就以可视范围为容器-->

            </div>
            <div class="listmore" style="height: 50px;">...</div>
        </div>
    </div>
</div>
<script type="text/javascript" >
    $(function () {
        $('pre code').each(function(i, block) {
            hljs.highlightBlock(block);
        });

        //loading特效插件，你可以选择其它效果配合使用
        var spinopts = {
            //lines: 13, // The number of lines to draw
            //length: 28, // The length of each line
            width: 2, // The line thickness
            radius: 10, // The radius of the inner circle
            scale: 1, // Scales overall size of the spinner
            corners: 1, // Corner roundness (0..1)
            color: '#999', // #rgb or #rrggbb or array of colors
            opacity: 0.25, // Opacity of the lines
            rotate: 0, // The rotation offset
            direction: 1, // 1: clockwise, -1: counterclockwise
            speed: 1, // Rounds per second
            trail: 60, // Afterglow percentage
            fps: 20, // Frames per second when using setTimeout() as a fallback in IE 9
            zIndex: 2e9, // The z-index (defaults to 2000000000)
            className: 'spinner', // The CSS class to assign to the spinner
            top: '50%', // Top position relative to parent
            left: '50%', // Left position relative to parent
            shadow: false, // Whether to render a shadow
            position:'relative',
        };

        //初始化
        $('#c').mload({
            protect:'.loadmorec,.loadmore',//保护指定的容器下的内容，可指定多个需要保护的容器
            mab:50,
            filter:function (i) {//同时这也是一个初始方法，可以做一些事件操作，return的数据作为初始过滤条件
                var filter = {}
                filter = $('#cf').change(function () {
                    //条件改变时重新加载列表
                    i.setfilter($(this).serializeArray()).reload()
                }).submit(function (e) {
                    e.preventDefault();
                    //提交过滤表单时重新加载列表
                    i.setfilter($(this).serializeArray()).reload()
                    return false;
                }).serializeArray()
                return filter;
            },//初始数据过滤条件
            loadprocess:function (i) {//过滤参数
                var target = $(i.target)
                var filter = i.filter
                filter['limit'] = 10
                filter['skip'] = i.offset* filter['limit']

                i.ajax({
                    url:'c.php',
                    type:'GET',
                    data:filter,
                    success:function (response,status) {
                        if(response.end===true){
                            i.end=true;
                        }
                        $(target).append(response)
                        $('.loadmorec').text('加载完成')

                    },
                    error:function (response,status) {
                        //do something
                    }
                })
            },
            beforeLoad:function (i) {
                var spinner = new Spinner(spinopts).spin($('.loadmorec').html('').get(0));
            },
            completed:function (jqHXR) {
                $('.loadmorec').text('没有更多内容')
            }
        })

        //插件初始化
        $('#list').mload({
            protect:'',
            mab:100,
            filter:function (i) {//同时这也是一个初始方法，可以做一些事件操作，return的数据作为初始过滤条件
                var filter = {}
                filter = $('#demo').change(function () {
                    //条件改变时重新加载列表
                    i.setfilter($(this).serializeArray()).reload()
                }).submit(function (e) {
                    e.preventDefault();
                    //提交过滤表单时重新加载列表
                    i.setfilter($(this).serializeArray()).reload()
                    return false;
                }).serializeArray()
                return filter;
            },//传入初始条件
            loadprocess:function (i) {//过滤参数
                var target = $(i.target)
                var filter = i.filter
                filter['limit'] = 5
                filter['skip'] = i.offset* filter['limit']

                i.ajax({
                    url:'p.php',
                    type:'GET',
                    dataType:'html',
                    data:filter,
                    success:function (response,status) {
                        $(target).append(response)
                        $('.listmore').text('加载完成')
                    },
                    error:function (response,status) {
                        //do something
                    }
                })
            },
            beforeLoad:function (i) {
                var spinner = new Spinner(spinopts).spin($('.listmore').html('').get(0));
            },
            completed:function (jqHXR) {
                $('.listmore').text('没有更多内容')
            }
        })
    })


</script>

</body>
</html>